Skip to content

Fix/oauth jwt cookie - #153

Merged
DioChuks merged 5 commits into
BuidlZone-Labs:mainfrom
dubemoyibe-star:fix/oauth-jwt-cookie
Jun 28, 2026
Merged

Fix/oauth jwt cookie#153
DioChuks merged 5 commits into
BuidlZone-Labs:mainfrom
dubemoyibe-star:fix/oauth-jwt-cookie

Conversation

@dubemoyibe-star

@dubemoyibe-star dubemoyibe-star commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR fixes the insecure transmission of JWT tokens during the Google OAuth flow by removing the token from URL query parameters and replacing it with a secure delivery mechanism.

Closes #138

Problem

The Google OAuth callback previously redirected users to the frontend using:

https://frontend.example.com?token=<jwt>

Passing authentication tokens in URLs exposes them to browser history, server logs, proxy logs, analytics tools, and Referer headers, increasing the risk of token leakage.

Changes

  • Removed JWT tokens from OAuth redirect query parameters
  • Implemented secure HTTP-only cookie delivery for authentication tokens
  • Updated the OAuth callback flow to set the token as a cookie
  • Updated frontend authentication handling to use the new authentication mechanism
  • Preserved existing login functionality while improving security

Security Improvements

The authentication token is now:

  • Stored in an HTTP-only cookie
  • Inaccessible to client-side JavaScript
  • Protected from accidental exposure through URLs
  • No longer included in browser history or server logs

Testing

  • Verified successful Google OAuth login flow
  • Confirmed JWT is not present in redirect URLs
  • Verified authentication cookie is set correctly
  • Confirmed frontend authentication continues to function correctly

Checklist

  • JWT removed from URL query parameters
  • Secure token delivery mechanism implemented
  • Frontend updated to support the new flow
  • OAuth authentication flow tested successfully
  • Existing functionality preserved

Summary by CodeRabbit

  • New Features
    • Login and signup now validate input with schemas and return structured Validation failed responses.
    • Google OAuth callback now stores the auth token in an httpOnly cookie and redirects without exposing the token in the URL.
  • Bug Fixes
    • Auth token handling now supports tokens from cookies as well as authorization headers.
    • Stricter handling of invalid and NoSQL injection-like inputs for login/signup.
  • Tests
    • Added/updated Jest coverage for cookie-based auth and enhanced login/signup validation failure cases.

@drips-wave

drips-wave Bot commented Jun 27, 2026

Copy link
Copy Markdown

@dubemoyibe-star Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c0e355b6-d735-41c5-8467-fb45039ac33e

📥 Commits

Reviewing files that changed from the base of the PR and between c58efec and e1d4681.

📒 Files selected for processing (2)
  • src/middlewares/jwt.ts
  • tests/auth.middleware.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/auth.middleware.test.ts

📝 Walkthrough

Walkthrough

Adds Zod schemas for login and signup validation, switches Google OAuth callback token delivery to an httpOnly cookie, updates token extraction to read cookies, and expands tests for validation and cookie-based auth.

Changes

Auth Validation and Cookie Token Delivery

Layer / File(s) Summary
Zod auth validation schemas
src/validators/auth.validator.ts
Defines LoginSchema and SignupSchema with email and non-empty string rules, and exports inferred LoginInput/SignupInput types.
Controller validation with Zod safeParse
src/controllers/login.controller.ts, src/controllers/signup.controller.ts
Both controllers replace manual presence checks with safeParse; failures return HTTP 400 with { error: 'Validation failed', messages: z.treeifyError(...) }; success reads fields from parsed.data.
OAuth callback and cookie token extraction
src/routes/auth.route.ts, src/utils/helper.ts, src/middlewares/jwt.ts
The Google OAuth callback sets the JWT as an httpOnly cookie (secure in production, sameSite: 'lax', 1-hour maxAge) and redirects to FRONTEND_URL; token extraction now falls back to the token cookie when no Authorization bearer is present; JwtVerify now returns jwt.verify(...) directly.
Validation and cookie auth tests
tests/login.controller.test.ts, tests/signup.controller.test.ts, tests/auth.middleware.test.ts
Login tests cover missing fields, invalid email, and NoSQL injection payloads. Signup tests update the validation error shape and add injection cases. Auth middleware tests cover cookie-based JWT acceptance and rejection.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 No token trails in the URL now,
A cookie carries it safe somehow.
Zod checks the fields before they run,
The rabbit hops off with a safer fun.

Possibly related PRs

Suggested reviewers

  • DioChuks
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The cookie-based token delivery is implemented, but the frontend integration update required by #138 is not shown in the changed files. Add the frontend changes that consume the cookie-based token flow, or document why the existing frontend already supports it.
Out of Scope Changes check ⚠️ Warning The login/signup validation and JWT middleware changes are unrelated to the OAuth token-transmission fix. Split or remove the login/signup validation and JWT middleware changes unless they are part of the intended OAuth fix.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately points to the OAuth JWT cookie fix.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/validators/auth.validator.ts (1)

3-14: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Prefer Zod 4’s documented { error: ... } form here.

The PR context documents Zod 4’s unified error parameter, but these schemas still use positional string overloads. Switching now avoids relying on legacy signatures across all four validators.

Proposed refactor
 export const LoginSchema = z.object({
-  email: z.string().email('Invalid email format'),
-  password: z.string().min(1, 'Password is required'),
+  email: z.string().email({ error: 'Invalid email format' }),
+  password: z.string().min(1, { error: 'Password is required' }),
 });
@@
 export const SignupSchema = z.object({
-  name: z.string().min(1, 'Name is required'),
-  email: z.string().email('Invalid email format'),
-  password: z.string().min(1, 'Password is required'),
+  name: z.string().min(1, { error: 'Name is required' }),
+  email: z.string().email({ error: 'Invalid email format' }),
+  password: z.string().min(1, { error: 'Password is required' }),
 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/validators/auth.validator.ts` around lines 3 - 14, Update the Zod
validators in LoginSchema and SignupSchema to use Zod 4’s documented { error:
... } option instead of positional string messages. Replace the current string
arguments on email() and min() with the unified error form for all four field
validators so the auth schema definitions align with the newer API and avoid
legacy overloads.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/utils/helper.ts`:
- Around line 12-13: The token extraction logic in extractToken is too
permissive because it accepts any Authorization header with a second segment and
lets it override the cookie; update it so only a Bearer authorization header is
used before falling back to parseCookie(req.headers.cookie, 'token'). Keep the
existing extractToken behavior otherwise, but add an explicit scheme check in
the authorization parsing path so Basic and other non-Bearer headers do not
block a valid cookie token.

In `@src/validators/auth.validator.ts`:
- Around line 10-13: The SignupSchema name field currently uses
z.string().min(1), which still allows whitespace-only values to pass through
parsed.data.name. Update the name validator in SignupSchema to trim the input
before applying the requiredness check, so blank display names are rejected
consistently while keeping the existing validation message behavior.

In `@tests/auth.middleware.test.ts`:
- Around line 58-76: The invalid-cookie test is mocking JwtVerify with a plain
Error, which does not match the real verification failure shape used by
authGuard and handleAuthError. Update the test in auth.middleware.test.ts to
simulate the actual jwt.JsonWebTokenError contract from src/middlewares/jwt.ts
so the authGuard path is exercised as production handles it, and keep the
assertions aligned with the Unauthorized: Invalid token mapping.

---

Nitpick comments:
In `@src/validators/auth.validator.ts`:
- Around line 3-14: Update the Zod validators in LoginSchema and SignupSchema to
use Zod 4’s documented { error: ... } option instead of positional string
messages. Replace the current string arguments on email() and min() with the
unified error form for all four field validators so the auth schema definitions
align with the newer API and avoid legacy overloads.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 493416db-f4f9-4870-a0fe-104ba151af82

📥 Commits

Reviewing files that changed from the base of the PR and between 95dc218 and 36e727d.

📒 Files selected for processing (8)
  • src/controllers/login.controller.ts
  • src/controllers/signup.controller.ts
  • src/routes/auth.route.ts
  • src/utils/helper.ts
  • src/validators/auth.validator.ts
  • tests/auth.middleware.test.ts
  • tests/login.controller.test.ts
  • tests/signup.controller.test.ts

Comment thread src/utils/helper.ts
Comment thread src/validators/auth.validator.ts
Comment thread tests/auth.middleware.test.ts
@DioChuks
DioChuks self-requested a review June 28, 2026 12:58
@DioChuks

Copy link
Copy Markdown
Contributor

@dubemoyibe-star pls resolve coderabbit requested changes

@dubemoyibe-star

Copy link
Copy Markdown
Contributor Author

@DioChuks
I'm on it

dubemoyibe-star and others added 3 commits June 28, 2026 19:44
@dubemoyibe-star

Copy link
Copy Markdown
Contributor Author

@DioChuks
code rabbit review changes implemeted
Is this pr satisfactory to you

@DioChuks

Copy link
Copy Markdown
Contributor

Well done.

@DioChuks
DioChuks merged commit d04f46e into BuidlZone-Labs:main Jun 28, 2026
1 of 2 checks passed
@dubemoyibe-star
dubemoyibe-star deleted the fix/oauth-jwt-cookie branch June 30, 2026 09:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix the unsafe Transmission of JWT Token in URL Query Parameters.

2 participants